/*                                                                                                                           
 * JFFS3 -- Journalling Flash File System, Version 3.                                                                        
 *                                                                                                                           
 * Copyright (C) 2006  Ferenc Havasi <havasi@inf.u-szeged.hu>,                                                               
 *                     Zoltan Sogor <weth@inf.u-szeged.hu>,                                                                  
 *                     Matyas Majzik <admin@newarcana.com>,                                                               
 *                     University of Szeged, Hungary                                                                         
 *
 * This software is distributed under the GNU GPL v2.
 * For licensing information, see the file 'LICENCE' in this directory.                                                             
 *                                                                                                                           
 */

#ifndef __FLASH_API_H__
#define __FLASH_API_H__

#include <stdint.h>
#include <linux/types.h>
#include "kernel.h"

#define DO_DELAYS 32
// delays must be in usec
#define ACCESS_DELAY 50 //10 usec
#define PROGRAMM_DELAY 200 //200 usec
#define ERASE_DELAY 2000 //2 msec

#define FLASH_CLOSED 0
#define FLASH_SETUP 1
#define FLASH_PAGE_UNALLOCATED 0
#define FLASH_PAGE_ALLOCATED 1
#define FLASH_PAGE_WRITTEN 2
#define FLASH_BLOCK_READY 0
#define FLASH_BLOCK_BAD 1
#define FLASH_ERASE_BYTE 0xFF

//return codes
#define FLASH_INVALID -1
#define FLASH_INVALID_OFFSET -8
#define FLASH_OUT_OF_RANGE -9
#define FLASH_PAGE_ALREADY_WRITTEN -2
#define FLASH_READ_ERROR -4
#define FLASH_BAD_BLOCK -3

struct flash_descriptor
    {
    /*flash physical parameters*/
    uint64_t size;
    uint32_t erase_size;
    uint32_t page_size;
    /*flash filesystem parameters*/
    uint32_t block_size;
    uint32_t bg_size;

    uint32_t flags;
    int (*read)(uint64_t ofs, uint64_t len, uint64_t *retlen, uint8_t *buf);
    int (*write)(uint64_t ofs, uint64_t len, uint64_t *retlen, const uint8_t *buf);
    int (*writev)(const struct kvec *vecs, uint64_t count, uint64_t to, uint64_t *retlen);
    int (*erase)(uint64_t ofs, uint64_t len);
    int (*block_markbad)(uint64_t ofs);
    int (*block_isbad)(uint64_t ofs);
    int (*point) (struct flash_descriptor *mtd, uint64_t from, uint64_t len, uint64_t *retlen, u_char **mtdbuf);
    void (*unpoint) (struct flash_descriptor *mtd, u_char * addr, uint64_t from, uint64_t len);
    };

struct page_descriptor
    {
    uint_least8_t status;
    uint8_t *data;
    };

struct eraseblock_descriptor
    {
    uint32_t erase_count;
    uint_least8_t status;
    struct page_descriptor *pages;
    };

struct flash_memory
    {
    uint_least8_t status;
    struct eraseblock_descriptor *ebs;
    uint32_t erase_blocks;
    uint32_t erase_block_pages; //pages per erase blocks
    };

int flash_setup(struct flash_descriptor *fl_d);
int flash_close();
struct flash_descriptor *flash_get_descriptor();

int flash_read(uint64_t ofs, uint64_t len, uint64_t *retlen, uint8_t *buf);
int flash_write(uint64_t ofs, uint64_t len, uint64_t *retlen, const uint8_t *buf);
int flash_writev(const struct kvec *vecs, uint64_t count, uint64_t to, uint64_t *retlen);
int flash_erase_block(uint64_t ofs, uint64_t len);

int flash_mark_bad_block(uint64_t ofs);
int flash_is_bad_block(uint64_t ofs);
int flash_page_is_written(uint64_t ofs);

int flash_to_disk(const char *file_name);   //there should be no extension in filename
int flash_from_disk(const char *file_name); //there should be no extension in filename

#endif /*__FLASH_API_H__ */
